/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:此文件是为了建立两个网络初始化函数，根据外部的选择调用8266或者5500，必须使能at device 和 w5500
 * Date           Author       Notes
 * 2021-04-05     wyj           1.0.0
 */
#include <NET/net.h>
#include <rtthread.h>
#include <rtdevice.h>
//#include "easyflash.h"
#include <board.h>
#include "drv_spi.h"
#include <string.h>
//extern struct netdev *netdev_default;

#define DBG_TAG "fsc.net"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>

#ifdef PKG_USING_AT_DEVICE
#define USE_NET_DEV_8266 0x01
static struct at_device_esp8266 esp;
#include <at_device_esp8266.h>
#else
#define USE_NET_DEV_8266 0x00
#endif
#ifdef WIZ_USING_W5500
#define USE_NET_DEV_5500 0x02
#include <wiz.h>
#else
#define USE_NET_DEV_5500 0x00
#endif

static NetConfig net_cfg; 

// 通过获取ip地址分配信息, 检测网络是否连接成功
int net_is_connected(void) {
    struct netdev *netdev = RT_NULL;
    netdev = netdev_get_first_by_flags(NETDEV_FLAG_UP);
    char *ipaddr = inet_ntoa(netdev->ip_addr);
    if (netdev->ip_addr.addr > 0) {
        LOG_I("Net init success!!");
        LOG_I("IP addr: %s", ipaddr);
        return 1;
    }
    return 0;
}

#ifdef PKG_USING_AT_DEVICE
int esp8266_device_register(void)
{
    struct at_device_esp8266 *esp8266 = &esp;

    return at_device_register(&(esp8266->device), esp8266->device_name, esp8266->client_name,
                              AT_DEVICE_CLASS_ESP8266, (void *)esp8266);
}

int esp8266_init(char *sta_ssid, char *sta_pwd)
{
    esp.device_name = ESP8266_DEIVCE_NAME;
    esp.client_name = ESP8266_CLIENT_NAME;
    esp.wifi_ssid = sta_ssid;
    esp.wifi_password = sta_pwd;
    // LOG_D("esp8266 init wifi_ssid: %s!!", esp.wifi_ssid);
    // LOG_D("esp8266 init wifi_pwd: %s!!", esp.wifi_password);
    esp.recv_line_num = ESP8266_RECV_BUFF_LEN;
    return esp8266_device_register();
}
#endif

// mqtt保存配置到env中
void net_set_conf(struct NetConfig cfg) 
{
    ef_set_env("net_type", &cfg.NET_TYPE);
    ef_set_env("net_wifi_ssid", &cfg.NET_WIFI_SSID);
    ef_set_env("net_wifi_pwd", &cfg.NET_WIFI_PWD);
    ef_set_env("net_eth_mac", &cfg.NET_ETH_MAC);
}

// mqtt从env中读取配置
struct NetConfig net_get_conf() 
{
    struct NetConfig cfg;
    snprintf(cfg.NET_TYPE, sizeof(cfg.NET_TYPE), "%s", ef_get_env("net_type"));
    snprintf(cfg.NET_WIFI_SSID, sizeof(cfg.NET_WIFI_SSID), "%s", ef_get_env("net_wifi_ssid"));
    snprintf(cfg.NET_WIFI_PWD, sizeof(cfg.NET_WIFI_PWD), "%s", ef_get_env("net_wifi_pwd"));
    snprintf(cfg.NET_ETH_MAC, sizeof(cfg.NET_ETH_MAC), "%s", ef_get_env("net_eth_mac"));
    return cfg;
}

// 网络初始化
uint8_t net_init()
{
    // 获取网络类型和配置
    uint8_t net_type = 0;
    if (ef_get_env_blob("net_type", &net_cfg.NET_TYPE, sizeof(net_cfg.NET_TYPE), 0) == 0)
    {
        net_type = DEFAULT_NET_TYPE;
    } else{
        net_type = atoi(net_cfg.NET_TYPE);
    }
    if(net_type == 0)
    {
        net_type = DEFAULT_NET_TYPE;
    }
    if (ef_get_env_blob("net_wifi_ssid", &net_cfg.NET_WIFI_SSID, sizeof(net_cfg.NET_WIFI_SSID), 0) == 0) {
        snprintf(net_cfg.NET_WIFI_SSID, sizeof(net_cfg.NET_WIFI_SSID), "%s", DEFAULT_NET_WIFI_SSID);
    }
    if (ef_get_env_blob("net_wifi_pwd", &net_cfg.NET_WIFI_PWD, sizeof(net_cfg.NET_WIFI_PWD), 0) == 0) {
        snprintf(net_cfg.NET_WIFI_PWD, sizeof(net_cfg.NET_WIFI_PWD), "%s", DEFAULT_NET_WIFI_PWD);
    }
    if (ef_get_env_blob("net_eth_mac", &net_cfg.NET_ETH_MAC, sizeof(net_cfg.NET_ETH_MAC), 0) == 0) {
        snprintf(net_cfg.NET_ETH_MAC, sizeof(net_cfg.NET_ETH_MAC), "%s", DEFAULT_NET_ETH_MAC);
    }

    LOG_I("");
    LOG_I("============NET CONFIG=============");
    LOG_I("| TYPE\t| %d\t\t\t|", net_type);
    LOG_I("| WIFI_SSID\t| %s\t\t|", net_cfg.NET_WIFI_SSID);
    LOG_I("| WIFI_PWD\t| %s\t\t|", net_cfg.NET_WIFI_PWD);
    LOG_I("| ETH_MAC\t| %s\t|", net_cfg.NET_ETH_MAC);
    LOG_I("=======================================");
    
    uint8_t wait = 0;
    struct netdev *netdev = RT_NULL;
    if ((net_type != 1) && (net_type != 2))
    {
        LOG_D("net type is wrong!!");
        return 1;
    }

#ifdef PKG_USING_AT_DEVICE
    else if (USE_NET_DEV_8266 & net_type) //初始化 8266网络
    {
        if (esp8266_init(net_cfg.NET_WIFI_SSID, net_cfg.NET_WIFI_PWD))
        {
            LOG_D("esp8266 init wrong!!");
            return 1;
        }
    }
#endif

#ifdef WIZ_USING_W5500
    else if (USE_NET_DEV_5500 & net_type) //初始化 5500网络
    {
        W5500_GPIO_CLK_ENABLE();
        rt_hw_spi_device_attach(W5500_SPI, W5500_SPI0, W5500_CS_GPIO, W5500_CS_GPIO_PIN);
        // 初始化mac地址
        if (wiz_init(net_cfg.NET_ETH_MAC))
        {
            LOG_D("5500 init wrong!!");
            return 1;
        }
    }
#endif
    else
    {
        LOG_D("there is't netdev_type%d", net_type);
        return 1;
    }

    while (wait < 3)
    {
        netdev = netdev_get_first_by_flags(NETDEV_FLAG_UP);
        if (netdev_is_link_up(netdev))
        {
            LOG_D("net link up!!");
            return 0;
        }
        wait++;
        rt_thread_mdelay(500);
    }
    LOG_D("net link failed!!");
    return 1;
}

#ifdef FINSH_USING_MSH
// MSH_CMD_EXPORT(net_set_env, config net and save to easyflash);
#endif /* FINSH_USING_MSH */
